package net.llz.service.impl;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import net.llz.constant.CacheKey;
import net.llz.enums.BizCodeEnum;
import net.llz.exception.BizException;
import net.llz.interceptor.LoginInterceptor;
import net.llz.model.LoginUser;
import net.llz.request.CartItemRequest;
import net.llz.service.CartService;
import net.llz.service.ProductService;
import net.llz.vo.CartItemVO;
import net.llz.vo.CartVO;
import net.llz.vo.ProductVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CartServiceImpl implements CartService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ProductService productService;
    @Override
    public void addToCart(CartItemRequest cartItemRequest) throws BizException {

        long productId= cartItemRequest.getProductId();
        int buyNum = cartItemRequest.getBuyNum();


        //获取购物车
        BoundHashOperations<String, Object, Object> myCart = getMyCartOps();

        //System.out.println(myCart);
       // Object cacheObj = myCart.get(productId);
         Object cacheObj = myCart.get(String.valueOf(productId));



        String result = "";

        if (cacheObj!=null){
            result = String.valueOf(cacheObj);
        }

        //long productId1= cartItemRequest.getProductId();
        if (StringUtils.isBlank(result)){
            //不存在商品
            CartItemVO cartItemVO= new CartItemVO();
            ProductVO productVO= productService.findDetailById(productId);
            if (productVO == null){throw  new BizException(BizCodeEnum.CART_FAIL);
            }
            cartItemVO.setAmount(productVO.getAmount());
            cartItemVO.setBuyNum(buyNum);
            cartItemVO.setProductImg(productVO.getCoverImg());
            cartItemVO.setProductId(productId);
            cartItemVO.setProductTitle(productVO.getTitle());
            myCart.put(String.valueOf(productId), JSON.toJSONString(cartItemVO));

        }else {
            //存在的商品
            CartItemVO cartItem = JSON.parseObject(result,CartItemVO.class);
            cartItem.setBuyNum(cartItem.getBuyNum() + buyNum);
            myCart.put(String.valueOf(productId), JSON.toJSONString(cartItem));

        }

    }

    @Override
    public void clean() {
        String cartKey = getCartKey();
        redisTemplate.delete(cartKey);
    }

    /**
     * 查看购物车
     * @return
     */
    @Override
    public CartVO getMyCart() {

        //获取全部购物项
        List<CartItemVO> cartItemVOList = buildCartItem(false);

        //封装成cartVO
        CartVO cartVO = new CartVO();
        cartVO.setCartItems(cartItemVOList);

        return cartVO;
    }

    /**
     * 删除购物项功能
     * @param productId
     */
    @Override
    public void deleteItem(long productId) {

        BoundHashOperations<String, Object, Object> myCart = getMyCartOps();
        myCart.delete(String.valueOf(productId));

    }

    /**
     * 修改购物车数量
     * @param cartItemRequest
     */
    @Override
    public void changeItemNum(CartItemRequest cartItemRequest) {
        BoundHashOperations<String, Object, Object> myCart = getMyCartOps();

        String cacheObj = (String) myCart.get(String.valueOf(cartItemRequest.getProductId()));
        CartItemVO cartItemVO =JSON.parseObject(cacheObj,CartItemVO.class);

        cartItemVO.setBuyNum(cartItemRequest.getBuyNum());
        myCart.put(String.valueOf(cartItemRequest.getProductId()), JSON.toJSONString(cartItemVO));


    }

    /**
     * 查询商品最新价格
     * @param productIdList
     * @return
     */
    @Override
    public List<CartItemVO> confirmOrderCartItems(List<Long> productIdList) {

        //获取全部购物车的购物项
        List<CartItemVO> cartItemVOList =  buildCartItem(true);
        //根据需要的商品id进行过滤，并清空对应的购物项
        List<CartItemVO> resultList =cartItemVOList.stream().filter(obj->{
            if (productIdList.contains(obj.getProductId())){
                this.deleteItem(obj.getProductId());
                return true;
            }

            return false;
        }).collect(Collectors.toList());

        return resultList;
    }

    /**
     * 获取最新的购物项
     * @param latestPrice
     * @return
     */
    private List<CartItemVO> buildCartItem(boolean latestPrice) {

        BoundHashOperations<String,Object,Object> myCart= getMyCartOps();

        List<Object> itemList =myCart.values();
        List<CartItemVO> cartItemVOList =new ArrayList<>();

        //拼接id列表最新价格
        List<Long> productIdList = new ArrayList<>();

        for (Object item : itemList){
           CartItemVO cartItemVO=  JSON.parseObject((String) item,CartItemVO.class);

            cartItemVOList.add(cartItemVO);
            productIdList.add(cartItemVO.getProductId());
        }

        //查询最新商品价格
        if (latestPrice){
            setProductListPrice(cartItemVOList,productIdList);
        }

        return cartItemVOList;
    }

    /**
     * 设置商品最新价格
     * @param cartItemVOList
     * @param productIdList
     */

    private void setProductListPrice(List<CartItemVO> cartItemVOList, List<Long> productIdList) {

        //批量查询
       List<ProductVO> productVOList=  productService.findProductsByIdBatch(productIdList);
       //分组
        Map<Long,ProductVO> maps = productVOList.stream().collect(Collectors.toMap(ProductVO::getId, Function.identity()));

        cartItemVOList.stream().forEach(item->{
            ProductVO productVO =maps.get(item.getProductId());
            item.setProductTitle(productVO.getTitle());
            item.setProductImg(productVO.getCoverImg());
            item.setAmount(productVO.getAmount());
        });
    }


    /**
     * 抽取购物车的通用方法
     * @return
     */
    private BoundHashOperations<String,Object,Object> getMyCartOps(){
        String cartKey = getCartKey();

        return  redisTemplate.boundHashOps(cartKey);
    }

    /**
     * 购物车key构建
     * @return
     */
    private String getCartKey(){
        LoginUser loginUser = LoginInterceptor.threadLocal.get();

        String cartKey = String.format(CacheKey.CART_KEY,loginUser.getId());
        return cartKey;
    }


}
